<template>
  <div class="container mx-auto p-4">


    <!-- 搜索和过滤区域 -->
    <div class="flex flex-col md:flex-row gap-4 mb-6" style="display: flex;">
      <div class="flex-1" style="width:500px">
        <el-input
            v-model="searchQuery"
            placeholder="搜索患者姓名、身份证或地址..."
            size="large"
            clearable
            @clear="handleReset"
            @keyup.enter="fetchAllPatients"
        >
          <template #append>
            <el-button @click="fetchAllPatients" icon="Search">搜索</el-button>
          </template>
        </el-input>
      </div>
      <div class="flex gap-2" style="width:200px">
        <el-select
            v-model="filterType"
            placeholder="糖尿病类型"
            size="large"
            clearable
            @change="fetchAllPatients"
        >
          <el-option
              v-for="type in diabetesTypes"
              :key="type.value"
              :label="type.label"
              :value="type.value"
          />
        </el-select>
      </div>
      <div class="flex justify-between items-center mb-6" >

        <el-button type="primary" @click="handleAdd" style="margin-left:20px">
          <el-icon><Plus /></el-icon> 新增患者
        </el-button>
      </div>
    </div>

    <!-- 状态显示 -->
    <div v-if="loading" class="py-12 flex justify-center">
      <el-icon class="is-loading" size="30"><Loading /></el-icon>
    </div>

    <el-alert
        v-else-if="error"
        :title="error"
        type="error"
        show-icon
        class="mb-6"
    />

    <!-- 患者卡片列表 -->
    <el-row v-else :gutter="20">
      <!-- 空状态处理 -->
      <div v-if="currentPagePatients.length === 0 && !loading" class="col-24 text-center py-12">
        <p class="text-gray-500">暂无符合条件的患者数据</p>
      </div>

      <el-col
          :xs="24" :sm="12" :md="8" :lg="6"
          v-for="patient in currentPagePatients"
          :key="patient.id"
          class="mb-4"
      >
        <el-card class="box-card" shadow="hover">
          <template #header>
            <div class="flex justify-between items-center">
              <span class="text-lg font-bold">{{ patient.name }}</span>
              <el-tag :type="getTypeColor(patient.diabetes_type)">
                {{ patient.diabetes_type }}
              </el-tag>
            </div>
          </template>

          <div class="patient-info space-y-3">
            <div class="flex items-center">
              <el-icon class="text-gray-400 mr-2"><User /></el-icon>
              <span>{{ patient.gender }}，{{ patient.age }}岁</span>
            </div>
            <div class="flex items-center">
              <el-icon class="text-gray-400 mr-2"><Phone /></el-icon>
              <span>{{ patient.contact }}</span>
            </div>
            <div class="flex items-center">
              <el-icon class="text-gray-400 mr-2"><CreditCard /></el-icon>
              <span>{{ formatIdCard(patient.id_card) }}</span>
            </div>
            <div class="flex items-center">
              <el-icon class="text-gray-400 mr-2"><Location /></el-icon>
              <span class="truncate">{{ patient.address }}</span>
            </div>
            <div class="flex items-center">
              <el-icon class="text-gray-400 mr-2"><Calendar /></el-icon>
              <span>{{ formatDate(patient.diagnosis_date) }}</span>
            </div>

            <div class="mt-4 pt-3 border-t border-gray-100">
              <h3 class="text-sm font-medium text-gray-900 mb-2">生活习惯</h3>
              <div class="flex flex-wrap gap-2">
                <el-tag size="small" type="info" v-if="patient.diet">
                  <el-icon><Food /></el-icon>
                  {{ patient.diet }}
                </el-tag>
                <el-tag size="small" type="warning" v-if="patient.smoking_status">
                  <el-icon><Smoking /></el-icon>
                  {{ patient.smoking_status }}
                </el-tag>
                <el-tag size="small" type="success" v-if="patient.drinking_status">
                  <el-icon><CoffeeCup /></el-icon>
                  {{ patient.drinking_status }}
                </el-tag>
              </div>
            </div>

            <!-- 操作按钮 -->
            <div class="mt-4 flex justify-end gap-2">
              <el-button size="small" type="primary" @click="handleEdit(patient)">
                <el-icon><Edit /></el-icon> 编辑
              </el-button>
              <el-button size="small" type="danger" @click="handleDelete(patient.id)">
                <el-icon><Delete /></el-icon> 删除
              </el-button>
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 分页控件 -->
    <div class="mt-8 flex justify-center" v-if="totalCount > 0">
      <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :total="totalCount"
          layout="total, sizes, prev, pager, next, jumper"
          @current-change="handlePageChange"
          @size-change="handleSizeChange"
      />
    </div>

    <!-- 新增/编辑弹窗 -->
    <el-dialog
        v-model="dialogVisible"
        :title="dialogType === 'add' ? '新增患者' : '编辑患者'"
        width="600px"
    >
      <el-form
          ref="patientForm"
          :model="formData"
          :rules="formRules"
          label-width="120px"
          class="space-y-4"
      >
        <!-- 新增时需要输入ID -->
        <el-form-item
            v-if="dialogType === 'add'"
            label="患者ID"
            prop="id"
        >
          <el-input
              v-model.number="formData.id"
              type="number"
              placeholder="请输入患者唯一ID"
          />
        </el-form-item>

        <el-form-item label="姓名" prop="name">
          <el-input v-model="formData.name" placeholder="请输入患者姓名" />
        </el-form-item>
        <el-form-item label="性别" prop="gender">
          <el-radio-group v-model="formData.gender">
            <el-radio label="男" />
            <el-radio label="女" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input v-model.number="formData.age" type="number" placeholder="请输入年龄" />
        </el-form-item>
        <el-form-item label="联系电话" prop="contact">
          <el-input v-model="formData.contact" placeholder="请输入联系电话" />
        </el-form-item>
        <el-form-item label="身份证号" prop="id_card">
          <el-input v-model="formData.id_card" placeholder="请输入身份证号" />
        </el-form-item>
        <el-form-item label="地址" prop="address">
          <el-input v-model="formData.address" placeholder="请输入家庭地址" />  <!-- 提示清晰 -->
        </el-form-item>
        <el-form-item label="糖尿病类型" prop="diabetes_type">
          <el-select v-model="formData.diabetes_type" placeholder="请选择类型">
            <el-option
                v-for="type in diabetesTypes"
                :key="type.value"
                :label="type.label"
                :value="type.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="诊断日期" prop="diagnosis_date">
          <el-date-picker
              v-model="formData.diagnosis_date"
              type="date"
              placeholder="选择诊断日期"
              value-format="YYYY-MM-DD"
          />
        </el-form-item>
        <el-form-item label="饮食习惯">
          <el-input v-model="formData.diet" placeholder="请输入饮食习惯" />
        </el-form-item>
        <el-form-item label="吸烟状态">
          <el-select v-model="formData.smoking_status">
            <el-option label="不吸烟" value="不吸烟" />
            <el-option label="偶尔吸烟" value="偶尔吸烟" />
            <el-option label="经常吸烟" value="经常吸烟" />
          </el-select>
        </el-form-item>
        <el-form-item label="饮酒状态">
          <el-select v-model="formData.drinking_status">
            <el-option label="不饮酒" value="不饮酒" />
            <el-option label="偶尔饮酒" value="偶尔饮酒" />
            <el-option label="经常饮酒" value="经常饮酒" />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button
            type="primary"
            @click="dialogType === 'add' ? handleSubmitAdd() : handleSubmitEdit()"
        >
          {{ dialogType === 'add' ? '新增' : '保存' }}
        </el-button>
      </template>
    </el-dialog>

  <!-- 删除确认弹窗 -->
  <el-dialog
      v-model="deleteDialogVisible"
      title="确认删除"
      width="400px"
      :before-close="() => (deleteDialogVisible = false)"
  >
    <p class="text-danger">确定要删除该患者信息吗？此操作不可撤销！</p>
    <template #footer>
      <el-button @click="deleteDialogVisible = false">取消</el-button>
      <el-button type="danger" @click="confirmDelete">确认删除</el-button>
    </template>
  </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, reactive, nextTick } from 'vue'
import axios from 'axios'
import {
  Plus, Edit, Delete, User, Phone, CreditCard,
  Location, Calendar, Food, Smoking, CoffeeCup, Loading,
} from '@element-plus/icons-vue'
import { ElMessage } from "element-plus";
import router from "@/router/index.js";

// 状态管理
const allPatients = ref([])
const currentPage = ref(1)
const pageSize = ref(10)
const loading = ref(false)
const error = ref(null)

// 搜索和筛选
const searchQuery = ref('')
const filterType = ref('')

// 糖尿病类型选项
const diabetesTypes = [
  { value: '1型', label: '1型糖尿病' },
  { value: '2型', label: '2型糖尿病' },
  { value: '妊娠期糖尿病', label: '妊娠期糖尿病' },
  { value: '其他特殊类型', label: '其他类型' }
]

// 弹窗相关状态
const dialogVisible = ref(false)
const deleteDialogVisible = ref(false)
const dialogType = ref('add')
const currentEditId = ref(null)
const deleteId = ref(null)

// 表单数据
const formData = reactive({
  id: null,
  name: '',
  gender: '男',
  age: null,
  contact: '',
  id_card: '',
  address: '',
  diabetes_type: '',
  diagnosis_date: '',
  diet: '',
  smoking_status: '',
  drinking_status: ''
})

// 表单验证规则
const formRules = reactive({
  id: [
    { required: true, message: '请输入患者ID', trigger: 'blur' },
    { type: 'number', message: 'ID必须为数字', trigger: 'blur' }
  ],
  name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
  gender: [{ required: true, message: '请选择性别', trigger: 'change' }],
  age: [
    { required: true, message: '请输入年龄', trigger: 'blur' },
    { type: 'number', min: 1, max: 119, message: '年龄必须在1-119之间', trigger: 'blur' }
  ],  address: [
    { required: true, message: '请输入家庭地址', trigger: 'blur' },  // 新增：地址必填
    { min: 1, max: 200, message: '地址长度为1-200个字符', trigger: 'blur' }  // 可选：长度限制
  ],
  contact: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
  id_card: [
    { required: true, message: '请输入身份证号', trigger: 'blur' },
    { min: 15, max: 18, message: '身份证号长度为15-18位', trigger: 'blur' }
  ],
  diabetes_type: [{ required: true, message: '请选择糖尿病类型', trigger: 'change' }],
  diagnosis_date: [{ required: true, message: '请选择诊断日期', trigger: 'change' }]
})

// 表单引用
const patientForm = ref(null)

// 核心：前端分页逻辑
const currentPagePatients = computed(() => {
  let filtered = allPatients.value.filter(patient => {
    const matchesSearch = !searchQuery.value ||
        patient.name.includes(searchQuery.value) ||
        patient.id_card?.includes(searchQuery.value) ||
        patient.address?.includes(searchQuery.value);
    const matchesType = !filterType.value || patient.diabetes_type === filterType.value;
    return matchesSearch && matchesType;
  });
  const startIndex = (currentPage.value - 1) * pageSize.value;
  const endIndex = startIndex + pageSize.value;
  return filtered.slice(startIndex, endIndex);
});

// 总条数
const totalCount = computed(() => {
  return allPatients.value.filter(patient => {
    const matchesSearch = !searchQuery.value ||
        patient.name.includes(searchQuery.value) ||
        patient.id_card?.includes(searchQuery.value) ||
        patient.address?.includes(searchQuery.value);
    const matchesType = !filterType.value || patient.diabetes_type === filterType.value;
    return matchesSearch && matchesType;
  }).length;
});

// 辅助函数
const getTypeColor = (type) => {
  const colors = { '1型': 'danger', '2型': 'warning', '妊娠期糖尿病': 'success', '其他特殊类型': 'info' };
  return colors[type] || '';
};

const formatDate = (dateStr) => {
  if (!dateStr) return '未知日期';
  const date = new Date(dateStr);
  return isNaN(date.getTime()) ? dateStr : date.toLocaleDateString('zh-CN');
};

const formatIdCard = (idCard) => {
  if (!idCard || idCard.length < 15) return idCard;
  return `${idCard.substring(0, 6)}****${idCard.substring(idCard.length - 4)}`;
};

// 获取全部患者数据
const fetchAllPatients = async () => {
  loading.value = true;
  error.value = null;
  try {
    const token = localStorage.getItem('access_token');
    const response = await axios.get('http://localhost:8000/patients/', {
      headers: { 'Authorization': `Bearer ${token}` }
    });
    allPatients.value = response.data;
  } catch (err) {
    error.value = err.response?.data?.detail || err.message || '获取数据失败';
    if (err.response?.status === 401) {
      ElMessage.error('请重新登录');
      await router.push('/login');
    }
  } finally {
    loading.value = false;
  }
};

// 新增操作
const handleAdd = () => {
  dialogType.value = 'add';

  // 重置表单
  Object.keys(formData).forEach(key => {
    formData[key] = key === 'gender' ? '男' : '';
  });

  nextTick(() => {
    patientForm.value?.resetFields();
  });

  dialogVisible.value = true;
};

// 编辑操作
const handleEdit = (patient) => {
  dialogType.value = 'edit';
  currentEditId.value = patient.id;

  // 填充表单数据
  Object.keys(formData).forEach(key => {
    if (key !== 'id') {  // 编辑时不修改ID
      formData[key] = patient[key] || (key === 'gender' ? '男' : '');
    }
  });

  dialogVisible.value = true;
};

// 提交新增
// 修改handleSubmitAdd方法，增加验证提示
const handleSubmitAdd = async () => {
  try {
    // 1. 表单基础验证
    await patientForm.value.validate();

    // 2. 准备表单数据（带类型转换）
    const formDataToSubmit = new FormData();

    // 数字类型必须转换（后端明确要求int）
    formDataToSubmit.append('id', Number(formData.id));       // 关键：转换为数字
    formDataToSubmit.append('age', Number(formData.age));     // 关键：转换为数字

    // 字符串类型（确保非空）
    formDataToSubmit.append('name', formData.name.trim());    // 去空格
    formDataToSubmit.append('gender', formData.gender);
    formDataToSubmit.append('contact', formData.contact.trim());
    formDataToSubmit.append('id_card', formData.id_card.trim());
    formDataToSubmit.append('address', formData.address.trim());
    formDataToSubmit.append('diabetes_type', formData.diabetes_type);
    formDataToSubmit.append('diagnosis_date', formData.diagnosis_date);

    // 3. 打印提交的数据（用于调试，确认字段名和值）
    console.log('提交的表单数据：');
    for (const [key, value] of formDataToSubmit.entries()) {
      console.log(`${key}: ${value} (类型: ${typeof value})`);
    }

    // 4. 发送请求
    const response = await axios.post(
        'http://localhost:8000/patients/add',
        formDataToSubmit,
        {
          headers: { 'Content-Type': 'multipart/form-data' }
        }
    );

    // 5. 成功处理
    allPatients.value.unshift(response.data);
    ElMessage.success('新增成功');
    dialogVisible.value = false;

  } catch (err) {
    // 6. 错误处理（核心：解析具体字段错误）
    console.error('新增失败详情：', err);

    if (err.response && err.response.data && err.response.data.detail) {
      // 解析后端返回的具体错误字段
      const errorDetails = err.response.data.detail;
      let errorMsg = '提交失败，错误字段：\n';

      // 映射字段名（后端字段名 → 中文显示）
      const fieldMap = {
        'id': '患者ID',
        'name': '姓名',
        'gender': '性别',
        'age': '年龄',
        'contact': '联系方式',
        'id_card': '身份证号',
        'address': '地址',
        'diagnosis_date': '诊断日期',
        'diabetes_type': '糖尿病类型'
      };

      // 遍历错误详情，拼接提示信息
      errorDetails.forEach(item => {
        const field = item.loc[1];  // 提取错误字段名（如'age'）
        const fieldName = fieldMap[field] || field;  // 转换为中文
        errorMsg += `- ${fieldName}：${item.msg}\n`;  // 拼接错误信息
      });

      ElMessage.error(errorMsg);  // 显示所有错误字段
    } else if (err.message) {
      ElMessage.error(err.message);
    } else {
      ElMessage.error('提交失败，请检查所有字段格式');
    }
  }
};

// 提交编辑
const handleSubmitEdit = async () => {
  try {
    await patientForm.value.validate();

    // 创建FormData对象
    const formDataToSubmit = new FormData();
    Object.entries(formData).forEach(([key, value]) => {
      if (key !== 'id' && value !== null && value !== undefined) {
        formDataToSubmit.append(key, value);
      }
    });

    // 调用后端更新接口 - 修复URL参数问题
    await axios.put(
        `http://localhost:8000/patients/${currentEditId.value}`,
        formDataToSubmit,
        {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }
    );

    // 前端即时更新
    const index = allPatients.value.findIndex(p => p.id === currentEditId.value);
    if (index !== -1) {
      // 更新除ID外的其他字段
      const updatedFields = {};
      Object.entries(formData).forEach(([key, value]) => {
        if (key !== 'id') {
          updatedFields[key] = value;
        }
      });
      allPatients.value[index] = { ...allPatients.value[index], ...updatedFields };
    }

    ElMessage.success('更新成功');
    dialogVisible.value = false;
  } catch (err) {
    console.error('编辑失败:', err);
    if (err.response) {
      if (err.response.status === 422) {
        // 处理详细的验证错误
        const errors = err.response.data.detail;
        const errorMessages = errors.map(item =>
            `${item.loc[item.loc.length - 1]}: ${item.msg}`
        ).join('\n');
        ElMessage.error(`验证失败:\n${errorMessages}`);
      } else {
        ElMessage.error(err.response.data.detail || '服务器错误');
      }
    } else {
      ElMessage.error('网络错误，请稍后重试');
    }
  }
};

// 删除操作
const handleDelete = (id) => {
  deleteId.value = id;
  deleteDialogVisible.value = true;
};

// 确认删除
const confirmDelete = async () => {
  try {
    // 调用后端删除接口 - 修复URL参数问题
    await axios.delete(`http://localhost:8000/patients/${deleteId.value}`);

    // 前端即时更新
    allPatients.value = allPatients.value.filter(p => p.id !== deleteId.value);
    ElMessage.success('删除成功');
    deleteDialogVisible.value = false;
  } catch (err) {
    console.error('删除失败:', err);
    ElMessage.error(err.response?.data?.detail || '删除失败');
  }
};

// 分页和搜索相关方法
const handlePageChange = (newPage) => {
  currentPage.value = newPage;
};

const handleSizeChange = (newSize) => {
  pageSize.value = newSize;
  currentPage.value = 1; // 重置为第1页
};

const handleReset = () => {
  searchQuery.value = '';
  filterType.value = '';
  currentPage.value = 1;
};

// 初始化加载
onMounted(() => {
  fetchAllPatients();
});
</script>

<style scoped>
.patient-info { font-size: 14px; color: #606266; }
.box-card {
  height: 100%;
  transition: all 0.3s;
}
.box-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
</style>